import {
  type Accessor,
  type Component,
  Index,
  type ParentProps,
  Show,
  createMemo,
  mergeProps,
} from "solid-js";
import { type NamedSlotTemplates, Slot } from "@lib/Slot";
import type { Value } from "../TextBox";
import EmptyContent from "@lib/empty/EmptyContent";
import type { JSX } from "solid-js/jsx-runtime";

export interface ListBoxItemSlots<T = {}> extends NamedSlotTemplates {
  default?: Component<{ data?: T }>;
}

export interface ListBoxItemProps<TItem = any>
  extends JSX.CustomAttributes<any> {
  data?: Accessor<TItem>;
  index?: number;
  ordered?: boolean;
  slots?: ListBoxItemSlots<TItem>;
  onClick?: (item: TItem, index: number) => void;
  disabled?: boolean;
  active?: boolean;
  action?: boolean;
}

export interface ListBoxSlots<TItem> extends NamedSlotTemplates {
  item: Component<ListBoxItemProps<TItem>>;
}

export type SelectedValue<T> = Value<T> | Value<T>[];

export interface ListBoxProps<TItem> extends ParentProps<any> {
  datas?: TItem[];
  slots?: ListBoxSlots<TItem>;
  ordered?: boolean;
  onClick?: (item: TItem, index: number) => void;
}

const ListBoxDefaultProps: Partial<ListBoxProps<any>> = {
  ordered: false,
};

const ListBox = <T extends {}>(p: ListBoxProps<T>) => {
  const props = mergeProps(ListBoxDefaultProps, p);

  const datas = createMemo(() => {
    return props.datas as any[];
  });

  const handleItemClicked = (item: any, index: number) => {
    props.onClick?.(item, index);
  };

  return (
    <div class="list-group">
      <Show
        when={props.datas && props.datas.length > 0}
        fallback={
          <ListBoxItem action={false}>
            <EmptyContent></EmptyContent>
          </ListBoxItem>
        }
      >
        <Index each={datas()}>
          {(item, index) => (
            <Slot
              slot={props.slots?.item}
              context={{
                data: item!,
                index: index,
                ordered: props.ordered,
                onClick: handleItemClicked,
              }}
            >
              {(ctx) => <ListBoxItem {...ctx}></ListBoxItem>}
            </Slot>
          )}
        </Index>
      </Show>
    </div>
  );
};

export const ListBoxItem = <TItem extends {}>(
  props: ParentProps<ListBoxItemProps<TItem>>
) => {
  const innerClassList = createMemo(() => {
    return {
      ...props.classList,
      disbaled: props.disabled ?? false,
      active: props.active ?? false,
      "list-group-item-action": props.action ?? true,
    };
  });

  return (
    <div
      class="list-group-item "
      classList={innerClassList()}
      onClick={(e) => props.onClick?.(props.data!(), props.index!)}
    >
      <Slot slot={props.slots?.default} context={{ data: props.data?.() }}>
        {(ctx) => (
          <>
            {props.ordered ? `${props.index! + 1}` : ""}
            {props.children ?? ctx.data}
          </>
        )}
      </Slot>
    </div>
  );
};

export default Object.assign(ListBox, {
  Item: ListBoxItem,
});
